#include "Element.h"
#include "Liste.h"
#include "Element.h"
#include <stdlib.h>
#include <stdio.h>


void initialise(Liste *l)
{
	/*l = (Liste *)malloc(sizeof(Liste));*/
	l->prem = NULL;
	l->last = NULL;
}

int estVide(const Liste *l)
{
	return(l->prem == NULL);
}

unsigned int nbElements(const Liste * l)
{
	Cellule  *current;
	unsigned int nbElt;
	nbElt = 0;
	if(estVide(l)) {return 0;}
	current=l->prem;
	while(current != NULL)
	{
		nbElt=nbElt + 1;
		current=current->suivant;
	 }

	return nbElt;
}

void ajoutEnTete(ElemListe e, Liste *l)
{
	Cellule * temp;
	if(l->prem == NULL) {
		l->prem = (Cellule *) malloc (sizeof(Cellule));
		l->prem->info =e;
		l->prem->suivant = NULL;
		l->prem->precedent = NULL;
		l->last = l->prem;
	}else{
		temp = (Cellule*) malloc (sizeof(Cellule));
		temp->suivant=l->prem;
		temp->precedent = NULL;
		temp->info = e;
		l->prem->precedent  = temp;
		l->prem = temp;
	}
}


void ajoutEnQueue (ElemListe e, Liste * l)
{
	Cellule * temp;
	if(l->prem == NULL) {
		l->prem = (Cellule *) malloc (sizeof(Cellule));
		l->prem->info =e;
		l->prem->suivant = NULL;
		l->prem->precedent = NULL;
		l->last = l->prem;
	} else {
		temp=(Cellule *) malloc (sizeof(Cellule));
		temp->suivant=NULL;
		temp->info = e;
		temp->precedent = l->last;
		l->last->suivant = temp;
		l->last = temp;
	}
}

void suppressionEnTete(Liste *l)
{
	Cellule *temp;
	if(l->prem==l->last)
	{
		temp=l->prem;
		l->last = NULL;
		l->prem = NULL;
	}else{
	temp = l->prem;
	l->prem = l->prem->suivant;
	l->prem->precedent = NULL;
	}
	free(temp);
}

void videListe(Liste * l)
{
	while(!estVide(l))
	{
		suppressionEnTete(l);
	}
}

void affectation(Liste * l1, const Liste *l2)
{
	Cellule * current;
	if(!estVide(l1)){ videListe(l1); }
	current =l2->prem;
	while(current != NULL)
	{
		ajoutEnQueue(current->info , l1);
		current = current->suivant;
	}
}

int test1ErElementDansListe(const Liste *l)
{
	Cellule * current;
	if(estVide(l)){return 0;}
	current = l->prem->suivant;
	while(current != NULL)
	{
		if(testEgaliteElement(current->info,l->prem->info)){ return 1;}
		current=current->suivant;
	}
	return 0;
}

int testElementDansListe(const Liste *l, ElemListe e)
{
	Cellule * current;
	if(estVide(l)){return 0;}
	current = l->prem;
	while(current != NULL)
	{
		if(testEgaliteElement(current->info,e)){ return 1;}
		current=current->suivant;
	}
	return 0;
}

void insererElement(ElemListe e, Liste *l, unsigned int position)
{
	int i;
	Cellule * current;
	Liste Temp;
	current =l->prem;
	initialise(&Temp);
	i = 0;
	if(estVide(l) || (position == 0)) { ajoutEnTete(e,l);}
	else if(position  >= nbElements(l)) { ajoutEnQueue(e, l);}
	else {
		while(current != NULL)
		{
			if((i+1) == position)
				{
					ajoutEnQueue(e,&Temp);
					ajoutEnQueue(current->info, &Temp);
					current = current ->suivant;
					i++;
				}
			else {
				ajoutEnQueue(current->info, &Temp);
				current = current->suivant;
				i++;
				}
		}
		affectation(l , &Temp);
		videListe(&Temp);
	}
}

void deplaceElementListe(Liste *l)
{
    Cellule *pCellule = l->last;
    while(pCellule->precedent!=NULL)
    {
        pCellule->info=pCellule->precedent->info;
        pCellule=pCellule->precedent;
    }
}

ElemListe getPremierElemListe(const Liste *l)
{
    return l->prem->info;
}

void setPremierElemListe(Liste *l, ElemListe e)
{
    l->prem->info=e;
}


